package com.wzx.user.service.impl;

import com.alibaba.excel.util.DateUtils;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.*;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayUserInfoShareRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayUserInfoShareResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wzx.common.exception.LeadNewsException;
import com.wzx.common.pojo.resp.Result;
import com.wzx.user.business.shop.mapper.ReleaseDynamicMapper;
import com.wzx.user.constants.ZfbConstants;
import com.wzx.user.mapper.BindingMapper;
import com.wzx.user.mapper.NotesMapper;
import com.wzx.user.mapper.WalletMapper;
import com.wzx.user.pojo.Binding;
import com.wzx.user.pojo.Notes;
import com.wzx.user.pojo.Wallet;
import com.wzx.user.pojo.shop.pojo.ReleaseDynamic;
import com.wzx.user.pojo.shop.vo.ReleaseDynamicVo;
import com.wzx.user.service.PayZfbService;
import com.wzx.user.utils.AmountUtils;
import com.wzx.user.vo.PayVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @author wzx
 * @version 1.0
 * @date 2023/6/8 - 21:37
 * @description 标题
 */
@Slf4j
@Service
public class PayZfbServiceImpl implements PayZfbService {

    public final String RSA2 = "RSA2";
    public final String CHARSET = "UTF-8";

    @Value("${zfbPay.url}")
    private String URL;

    @Value("${zfbPay.appId}")
    private String APPID;

    @Value("${zfbPay.appPrivateKey}")
    private String APP_PRIVATE_KEY;

    @Value("${zfbPay.appCertPublicKey}")
    private String APP_CERT_PUBLIC_KEY;

    @Value("${zfbPay.alipayCertPublicKey}")
    private String ALIPAY_CERT_PUBLIC_KEY;

    @Value("${zfbPay.alipayRootCertPath}")
    private String ALIPAY_ROOT_CERT_PATH;

    @Value("${zfbPay.baseUrl}")
    private String BASE_URL;

    @Autowired
    private NotesMapper notesMapper;

    @Autowired
    private WalletMapper walletMapper;

    @Autowired
    private ReleaseDynamicMapper releaseDynamicMapper;

    @Autowired
    private BindingMapper bindingMapper;

    @Autowired
    private RedisTemplate redisTemplate;


    @Override
    public String userRechargeAmount(PayVo payVo) throws AlipayApiException, LeadNewsException {
        //1，查看用户充值金额是否正确
        if (payVo.getPrice() > ZfbConstants.Payment.MAX_RECHARGE_AMOUNT) {
            throw new LeadNewsException("单笔充值最高不能超过3000！");
        }

        //2，充值前，查询用户充值次数是否已达到上线
        Integer rechargeNum = (Integer) redisTemplate.opsForValue().get(ZfbConstants.Payment.RECHARGE_RECORD + payVo.getUserId());
        //log.info("用户：{}，今日已经充值");
        if (rechargeNum != null && rechargeNum >= ZfbConstants.Payment.MAX_NUM) {
            throw new LeadNewsException("今日充值次数已达上线！");
        }

        if (StringUtils.isEmpty(payVo.getZfbTitle())) {
            payVo.setZfbTitle("支付宝充值");
        }

        Notes notes = new Notes();
        notes.setType("支付宝充值");
        notes.setZfbTitle(payVo.getZfbTitle());
        notes.setPrice(AmountUtils.handlerAmountByInteger(payVo.getPrice()));
        notes.setUserId(payVo.getUserId());
        notes.setState("2"); //预充值
        notes.setMethod("1");
        notesMapper.insert(notes);

        CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
        certAlipayRequest.setServerUrl(URL);
        certAlipayRequest.setAppId(APPID);
        //应用私钥
        certAlipayRequest.setPrivateKey(APP_PRIVATE_KEY);
        certAlipayRequest.setFormat("json");
        certAlipayRequest.setCharset(CHARSET);
        certAlipayRequest.setSignType(RSA2);
        // 设置应用公钥证书路径
        certAlipayRequest.setCertPath(APP_CERT_PUBLIC_KEY);
        // 设置支付宝公钥证书路径
        certAlipayRequest.setAlipayPublicCertPath(ALIPAY_CERT_PUBLIC_KEY);
        // 设置支付宝根证书路径
        certAlipayRequest.setRootCertPath(ALIPAY_ROOT_CERT_PATH);

        AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);

        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //我的接口（APP支付TRADE_SUCCESS（交易成功）、TRADE_CLOSED（交易关闭）、TRADE_FINISHED（交易完成）三种状态均会触发异步通知）
        request.setNotifyUrl("http://" + BASE_URL + ":6001/user/payZfb/userRechargeCallback");
        //request.setNotifyUrl("");
        JSONObject bizContent = new JSONObject();

        //获取当前时间
        //Date date = new Date();
        //String format = DateUtils.format(new Date(), DateUtils.DATE_FORMAT_14);
        //订单号
        bizContent.put("out_trade_no", notes.getId() + "");
        //bizContent.put("out_trade_no", format + "00000");
        bizContent.put("total_amount", payVo.getPrice());
        bizContent.put("subject", payVo.getZfbTitle());
        bizContent.put("product_code", "QUICK_MSECURITY_PAY");

        request.setBizContent(bizContent.toString());
        AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
        if (response.isSuccess()) {
            log.info("生成订单信息成功！");
            return response.getBody();
        } else {
            log.info("生成订单信息失败！");
            throw new LeadNewsException("生成订单信息失败");
        }
    }

    @Override
    public void tradeStatusOk(String outTradeNo) {
        //查询历史记录
        Notes notes = notesMapper.selectById(outTradeNo);
        //修改记录
        notes.setState("1");
        notesMapper.updateById(notes);

        //给用户添加余额
        QueryWrapper<Wallet> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("uid", notes.getUserId());
        Wallet wallet = walletMapper.selectOne(queryWrapper);

        Integer addAmount = notes.getPrice();
        log.info("用户：{}，充值金额：{}", notes.getUserId(), addAmount);

        if (wallet == null) {
            //当数据为空 直接添加数据
            Wallet addWallet = new Wallet();
            addWallet.setBalance(addAmount);
            addWallet.setUid(notes.getUserId());
            walletMapper.insert(addWallet);
        } else if (wallet.getBalance() == null) {
            wallet.setBalance(addAmount);
            walletMapper.updateById(wallet);
        } else {
            //在原先基础上增加
            wallet.setBalance(wallet.getBalance() + addAmount);
            walletMapper.updateById(wallet);
        }

        //添加 次数
        String redisKey = ZfbConstants.Payment.RECHARGE_RECORD + notes.getUserId();
        redisTemplate.opsForValue().increment(redisKey, 1);
        //这里设置12小时过期
        redisTemplate.expire(redisKey, 12, TimeUnit.HOURS);
    }

    @Override
    public void tradeStatusError(String outTradeNo) {
        Notes notes = notesMapper.selectById(outTradeNo);
        //修改记录
        notes.setState("2");
        notes.setMethod("支付宝充值失败");
        notesMapper.updateById(notes);
    }

    @Override
    public String userRechargeOrder(PayVo payVo) throws AlipayApiException, LeadNewsException {
        ReleaseDynamic releaseDynamic = releaseDynamicMapper.selectById(payVo.getOrderId());
        if (releaseDynamic == null) {
            throw new LeadNewsException("未找到该商品！");
        }

        if (!releaseDynamic.getState().equals("1") || releaseDynamic.getOrderState().equals("2")) {
            throw new LeadNewsException("订单已被处理！");
        }

        Notes notes = new Notes();
        notes.setType("支付宝:闲置下单");
        notes.setPrice(AmountUtils.handlerAmountByInteger(payVo.getPrice()));
        notes.setUserId(payVo.getUserId());
        notes.setState("2"); //预充值
        notes.setMethod("3");
        notes.setOrderId(payVo.getOrderId());
        notesMapper.insert(notes);

        CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
        certAlipayRequest.setServerUrl(URL);
        certAlipayRequest.setAppId(APPID);
        //应用私钥
        certAlipayRequest.setPrivateKey(APP_PRIVATE_KEY);
        certAlipayRequest.setFormat("json");
        certAlipayRequest.setCharset(CHARSET);
        certAlipayRequest.setSignType(RSA2);
        // 设置应用公钥证书路径
        certAlipayRequest.setCertPath(APP_CERT_PUBLIC_KEY);
        // 设置支付宝公钥证书路径
        certAlipayRequest.setAlipayPublicCertPath(ALIPAY_CERT_PUBLIC_KEY);
        // 设置支付宝根证书路径
        certAlipayRequest.setRootCertPath(ALIPAY_ROOT_CERT_PATH);

        AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);

        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //我的接口（APP支付TRADE_SUCCESS（交易成功）、TRADE_CLOSED（交易关闭）、TRADE_FINISHED（交易完成）三种状态均会触发异步通知）
        request.setNotifyUrl("http://" + BASE_URL + ":6001/user/payZfb/userRechargeCallbackByOrder");
        //request.setNotifyUrl("");
        JSONObject bizContent = new JSONObject();

        //获取当前时间
        //Date date = new Date();
        //String format = DateUtils.format(new Date(), DateUtils.DATE_FORMAT_14);
        //订单号
        bizContent.put("out_trade_no", notes.getId() + "");
        //bizContent.put("out_trade_no", format + "00000");
        bizContent.put("total_amount", payVo.getPrice());
        bizContent.put("subject", "闲置下单");
        bizContent.put("product_code", "QUICK_MSECURITY_PAY");

        request.setBizContent(bizContent.toString());
        AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
        if (response.isSuccess()) {
            log.info("生成订单信息成功！");
            return response.getBody();
        } else {
            log.info("生成订单信息失败！");
            throw new LeadNewsException("生成订单信息失败");
        }
    }

    @Override
    public void tradeStatusOrderOk(String outTradeNo) throws LeadNewsException {
        //查询历史记录
        Notes notes = notesMapper.selectById(outTradeNo);
        notes.setState("1");
        notesMapper.updateById(notes);

        ReleaseDynamic releaseDynamic = releaseDynamicMapper.selectById(notes.getOrderId());
        if (releaseDynamic == null) {
            log.error("未找到该商品！");
            notesMapper.deleteById(notes.getId());
            throw new LeadNewsException("未找到该商品！");
        }

        if (!releaseDynamic.getState().equals("1") || releaseDynamic.getOrderState().equals("2")) {
            notesMapper.deleteById(notes.getId());
            log.error("订单已被处理！");
            throw new LeadNewsException("订单已被处理！");
        }

        //修改订单信息
        releaseDynamic.setState("2");
        releaseDynamic.setOrderUserId(notes.getUserId());
        releaseDynamic.setOrderState("2");
        releaseDynamicMapper.updateById(releaseDynamic);
    }

    @Override
    public void tradeStatusOrderError(String outTradeNo) {
        //查询历史记录
        Notes notes = notesMapper.selectById(outTradeNo);

        notesMapper.deleteById(notes.getId());
    }

    @Override
    public String userReleaseByZfb(ReleaseDynamicVo releaseDynamicVo) throws AlipayApiException, LeadNewsException {
        ReleaseDynamic releaseDynamic = new ReleaseDynamic();
        BeanUtils.copyProperties(releaseDynamicVo, releaseDynamic);
        //默认为已删除的订单
        releaseDynamic.setPrice(AmountUtils.handlerAmountByInteger(releaseDynamicVo.getPrice()));
        releaseDynamic.setReleaseUserDataState("2");
        releaseDynamicMapper.insert(releaseDynamic);

        CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
        certAlipayRequest.setServerUrl(URL);
        certAlipayRequest.setAppId(APPID);
        //应用私钥
        certAlipayRequest.setPrivateKey(APP_PRIVATE_KEY);
        certAlipayRequest.setFormat("json");
        certAlipayRequest.setCharset(CHARSET);
        certAlipayRequest.setSignType(RSA2);
        // 设置应用公钥证书路径
        certAlipayRequest.setCertPath(APP_CERT_PUBLIC_KEY);
        // 设置支付宝公钥证书路径
        certAlipayRequest.setAlipayPublicCertPath(ALIPAY_CERT_PUBLIC_KEY);
        // 设置支付宝根证书路径
        certAlipayRequest.setRootCertPath(ALIPAY_ROOT_CERT_PATH);

        AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);

        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //我的接口（APP支付TRADE_SUCCESS（交易成功）、TRADE_CLOSED（交易关闭）、TRADE_FINISHED（交易完成）三种状态均会触发异步通知）
        request.setNotifyUrl("http://" + BASE_URL + ":6001/user/payZfb/userReleaseByZfbCallback");
        //request.setNotifyUrl("");
        JSONObject bizContent = new JSONObject();

        //获取当前时间
        //Date date = new Date();
        //String format = DateUtils.format(new Date(), DateUtils.DATE_FORMAT_14);
        //订单号
        bizContent.put("out_trade_no", releaseDynamic.getId() + "");
        //bizContent.put("out_trade_no", format + "00000");
        bizContent.put("total_amount", releaseDynamicVo.getPrice());
        bizContent.put("subject", releaseDynamicVo.getTypeName());
        //bizContent.put("subject", "家政服务");
        bizContent.put("product_code", "QUICK_MSECURITY_PAY");

        request.setBizContent(bizContent.toString());
        AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
        if (response.isSuccess()) {
            log.info("生成订单信息成功！");
            return response.getBody();
        } else {
            log.info("生成订单信息失败！");
            releaseDynamicMapper.deleteById(releaseDynamic.getId());
            throw new LeadNewsException("生成订单信息失败");
        }
    }

    @Override
    public void userReleaseByZfbCallbackOk(String outTradeNo) throws LeadNewsException {
        ReleaseDynamic releaseDynamic = releaseDynamicMapper.selectById(outTradeNo);

        if (releaseDynamic == null) {
            log.error("未找到该商品！");
            throw new LeadNewsException("未找到该商品！");
        }

        Notes notes = new Notes();
        notes.setType("支付宝发布");
        notes.setPrice(releaseDynamic.getPrice());
        notes.setUserId(releaseDynamic.getReleaseUserId());
        notes.setState("1"); //预充值
        notes.setMethod("3");
        notesMapper.insert(notes);

        //修改订单信息
        releaseDynamic.setReleaseUserDataState("1");
        releaseDynamicMapper.updateById(releaseDynamic);
    }

    @Override
    public void userReleaseByZfbCallbackError(String outTradeNo) {
        //删除即可
        releaseDynamicMapper.deleteById(outTradeNo);
    }

    @Override
    public void userBindingZfb(Integer userId, String authCode) throws AlipayApiException, LeadNewsException {

        CertAlipayRequest certAlipayRequest = getCertAlipayRequest();
        AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();

        request.setCode(authCode);
        request.setGrantType("authorization_code");
        request.setRefreshToken("");
        AlipaySystemOauthTokenResponse response = alipayClient.certificateExecute(request);

        if (response.isSuccess()) {
            log.info("获取token成功！");
            String accessToken = response.getAccessToken();
            CertAlipayRequest certAlipayRequest1 = getCertAlipayRequest();
            AlipayClient alipayClient1 = new DefaultAlipayClient(certAlipayRequest1);
            AlipayUserInfoShareRequest request1 = new AlipayUserInfoShareRequest();
            AlipayUserInfoShareResponse responseToken = alipayClient1.certificateExecute(request1, accessToken);

            if (response.isSuccess()) {
                log.info("获取用户信息成功！");
                /*System.err.println("responseToken.getUserId() = " + responseToken.getUserId());
                System.err.println("responseToken.getUserName() = " + responseToken.getUserName());
                System.err.println("responseToken.getPhone() = " + responseToken.getPhone());*/

                QueryWrapper<Binding> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("userId", userId);
                Binding bindings = bindingMapper.selectOne(queryWrapper);
                if (bindings != null) {
                    //删除之前绑定
                    bindingMapper.deleteById(bindings.getId());
                }
                //再次绑定
                Binding binding = new Binding();
                binding.setTypeId("2");
                binding.setUserId(userId);
                binding.setZfbUserId(responseToken.getUserId());
                bindingMapper.insert(binding);
            } else {
                log.error("获取用户信息失败！");
                throw new LeadNewsException("获取用户信息失败");
            }

        } else {
            log.error("获取token失败！");
            throw new LeadNewsException("获取token失败");
        }


    }


    private CertAlipayRequest getCertAlipayRequest() {
        CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
        certAlipayRequest.setServerUrl(URL);
        certAlipayRequest.setAppId(APPID);
        //应用私钥
        certAlipayRequest.setPrivateKey(APP_PRIVATE_KEY);
        certAlipayRequest.setFormat("json");
        certAlipayRequest.setCharset(CHARSET);
        certAlipayRequest.setSignType(RSA2);
        // 设置应用公钥证书路径
        certAlipayRequest.setCertPath(APP_CERT_PUBLIC_KEY);
        // 设置支付宝公钥证书路径
        certAlipayRequest.setAlipayPublicCertPath(ALIPAY_CERT_PUBLIC_KEY);
        // 设置支付宝根证书路径
        certAlipayRequest.setRootCertPath(ALIPAY_ROOT_CERT_PATH);

        return certAlipayRequest;
    }


}
